package com.example.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.example.common.enums.OrderStatusEnum;
import com.example.common.enums.ResultCodeEnum;
import com.example.common.enums.RoleEnum;
import com.example.entity.Account;
import com.example.entity.Cart;
import com.example.entity.Orders;
import com.example.entity.OrdersItem;
import com.example.entity.dto.AmountDTO;
import com.example.entity.dto.OrdersDTO;
import com.example.exception.CustomException;
import com.example.mapper.OrdersMapper;
import com.example.service.CartService;
import com.example.service.OrdersService;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@Slf4j
@Service
public class OrdersServiceImpl implements OrdersService{

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private CartService cartService;

    @Resource
    private OrdersItemServiceImpl ordersItemService;

    @Override
    @Transactional
    public void addOrder(OrdersDTO ordersDTO) {
        Integer businessId = ordersDTO.getBusinessId();
        Account currentUser = TokenUtils.getCurrentUser();
        Integer userId = currentUser.getId();
        if (userId == null) {
            throw new CustomException(ResultCodeEnum.NO_AUTH);
        }
        List<Cart> cartList = cartService.selectUserCart(currentUser.getId(), businessId);
        if (CollUtil.isEmpty(cartList)) {
            throw new CustomException(ResultCodeEnum.NO_GOODS);
        }
        Orders orders = new Orders();
        orders.setBusinessId(businessId);
        String now = DateUtil.now();
        orders.setTime(now);
        orders.setPayType(ordersDTO.getPayType());
        orders.setDeliveryType(ordersDTO.getDeliveryType());
        orders.setUserId(userId);
        orders.setAddress(ordersDTO.getAddress());
        orders.setUser(ordersDTO.getUser());
        orders.setPhone(ordersDTO.getPhone());
        orders.setComment(ordersDTO.getComment());

        // 设置商品信息
        AmountDTO amountDTO = cartService.calcTotal(userId, businessId);

        // 设置总价
        BigDecimal amount = amountDTO.getAmount() != null ? amountDTO.getAmount() : BigDecimal.ZERO;
        // 判断配送类型，如果是骑手配送则总价加1（假设增加的配送费用为1）
        if ("骑手配送".equals(ordersDTO.getDeliveryType())) {
            amount = amount.add(BigDecimal.ONE);
        }
        orders.setAmount(amount);

        // 设置优惠金额
        orders.setDiscount(amountDTO.getDiscount());

        // 实际支付的金额
        BigDecimal actual = amountDTO.getActual() != null ? amountDTO.getActual() : BigDecimal.ZERO;
        // 判断配送类型，如果是骑手配送则总价加1（假设增加的配送费用为1）
        if ("骑手配送".equals(ordersDTO.getDeliveryType())) {
            actual = actual.add(BigDecimal.ONE);
        }
        orders.setActual(actual);

        // 得到购物车商品的总数
        Integer nums = cartList.stream().map(Cart::getNum).reduce(Integer::sum).orElse(0);
        orders.setName(cartList.get(0).getGoods().getName() + "等" + nums + "件商品");
        orders.setCover(cartList.get(0).getGoods().getImg());

        // 雪花算法生成唯一的ID作为订单号
        orders.setOrderNo(IdUtil.getSnowflakeNextIdStr());
        // 设置订单状态
        orders.setStatus(OrderStatusEnum.NO_PAY.getValue());
        this.add(orders);

        // 再设置订单的 详细信息
        for (Cart cart : cartList) {
            OrdersItem ordersItem = new OrdersItem();
            ordersItem.setOrderId(orders.getId());
            ordersItem.setGoodsName(cart.getGoods().getName());
            ordersItem.setGoodsImg(cart.getGoods().getImg());
            ordersItem.setPrice(cart.getGoods().getActualPrice());
            ordersItem.setNum(cart.getNum());
            ordersItem.setGoodsId(cart.getGoodsId());
            ordersItemService.add(ordersItem);
        }

        // 清空购物车
        cartService.deleteByBusiness(businessId, userId);
    }

    @Override
    public void add(Orders orders) {
        ordersMapper.insert(orders);
    }

    @Override
    @Transactional
    public void deleteById(Integer id) {
        ordersMapper.deleteById(id);
        // 删除订单详情
        ordersItemService.deleteByOrderId(id);
    }

    @Override
    @Transactional
    public void deleteBatch(List<Integer> ids) {
        for (Integer id : ids) {
            this.deleteById(id);
        }
    }

    @Override
    @Transactional
    public void updateById(Orders orders) {
        if(OrderStatusEnum.NO_SEND.getValue().equals(orders.getStatus())){
            orders.setPayTime(DateUtil.now());
        }
        ordersMapper.updateById(orders);
    }

    @Override
    public Orders selectById(Integer id) {
        return ordersMapper.selectById(id);
    }

    @Override
    public List<Orders> selectAll(Orders orders) {
        // 拿到当前的登录用户信息
        Account currentUser = TokenUtils.getCurrentUser();
        String role = currentUser.getRole();
        if (RoleEnum.BUSINESS.name().equals(role)) {
            orders.setBusinessId(currentUser.getId());
        }
        return ordersMapper.selectAll(orders);
    }

    @Override
    public PageInfo<Orders> selectPage(Orders orders, Integer pageNum, Integer pageSize) {
        // 拿到当前的登录用户信息
        Account currentUser = TokenUtils.getCurrentUser();
        String role = currentUser.getRole();
        if (RoleEnum.BUSINESS.name().equals(role)) {
            orders.setBusinessId(currentUser.getId());
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Orders> list = ordersMapper.selectAll(orders);
        return PageInfo.of(list);
    }

    @Override
    public List<Orders> selectUsageByBusinessId(Integer id) {
        return ordersMapper.selectUsageByBusinessId(id);
    }

    @Override
    public List<Orders> availableForRider(Orders orders) {
        return ordersMapper.availableForRider(orders);
    }

    @Override
    public List<Orders> selectAllRider(Orders orders) {
        return ordersMapper.selectAllRider(orders);
    }
}
